<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script type="application/javascript" charset="utf-8" src="../../common/CommonUtils.js"></script>
    <title>设计模式——复杂工厂模式</title>
    <script type="application/javascript" charset="utf-8">
        // 买什么车？去什么商店 -> 到达商店 -> 买车 -> 生产车 -> factory
        // 卖车的商店，可能有奥迪4S店，宝马4S店，奔驰4S点

        // super shop 卖车的基类
        // abstract class 不能被实例化
        function CarShop () {};
        // 在基类商店的原型对象上定义一个卖车的抽象方法
        CarShop.prototype = {
            // 还原构造器
            constructor : CarShop,
            sellCar : function (type) {
                this.abstractSell(type);
            },
            abstractSell : function () {
                throw new Error('This method is abstract!');
            }
        };
        // Benz 4s店
        // 继承基类商店，实现基类卖车的抽象方法
        function BenzCarShop () {};
        WL.extend(BenzCarShop, CarShop);
        // 复写父类的卖车方法
        BenzCarShop.prototype = {
            constructor : BenzCarShop,
            sellCar : function (type) {
                var car; // 定义变量保存要出售的车
                var types = ['BenzCar200','BenzCar300']; // 存放所有Benz系列的类型
                var flag = false; // 记录本店是否有买家需要的车型
                // 循环Benz4S店的车系列，有买家需要的，从工厂拿该系列的车，没有则提示没有
                for ( var t in types) {
                    if (types[t] === type) {
                        car = CarFactory.createCar(type);
                        flag = true;
                    }
                }

                if (flag) { // 如果有需要的车型，则返回
                    return car;
                } else { // 如果没有需要的车型，则提示客户
                    alert('本店没有'+type+'系列的车!');
                }
            }
        };

        // Bmw 4s店
        function BmwCarShop () {};
        WL.extend(BmwCarShop, CarShop);
        BmwCarShop.prototype = {
            constructor : BmwCarShop,
            sellCar : function (type) {
                var car;
                var types = ['BmwCarX4','BmwCarX5'];
                var flag = false;

                for (var t in types) {
                    if (types[t] === type) {
                        car = CarFactory.createCar(type);
                        flag = true;
                    }
                }

                if (flag) {
                    return car;
                } else {
                    alert('本店没有'+type+'型号的车');
                }
            }
        };

        // 单体模式，构建一个动态生产车的工厂
        var CarFactory = {
            createCar : function (type) {
                // 利用eval函数实现动态工厂
                var car = eval('new ' + type +'()');
                // 出厂前检测
                WL.Interface.ensureImplements(car, interfaceCar);
                return car;
            }
        };

        // 构造一个汽车类的接口实例
        var interfaceCar = new WL.Interface(interfaceCar, ['start','run']);

        // super car 汽车的基类  去实现汽车接口中的方法
        function BaseCar () {};
        // 在汽车基类的原型对象上实现接口中的方法
        BaseCar.prototype = {
            constructor : BaseCar,
            start : function () {
                alert(this.constructor.name + ' is starting ...!');
            },
            run : function () {
                alert(this.constructor.name + ' is running ...!');
            }
        };

        // Benz car 奔驰车系列
        // 需要注意的是，先继承父类，在扩展自身
        function BenzCar200 () {};
        WL.extend(BenzCar200, BaseCar);

        function BenzCar300 () {};
        WL.extend(BenzCar300, BaseCar);

        // Bmw car 宝马车系列
        function BmwCarX4 () {};
        WL.extend(BmwCarX4,BaseCar);
        function BmwCarX5 () {};
        WL.extend(BmwCarX5,BaseCar);

        var shop1 = new BenzCarShop();
        var car1 = shop1.sellCar('BenzCar200');
        var car2 = shop1.sellCar('BenzCar300');
        car1.start();
        car2.run();

        var shop2 = new BmwCarShop();
        var car3 = shop2.sellCar('BmwCarX4');
        var car4 = shop2.sellCar('BmwCarX5');
        car3.start();
        car4.run();

    </script>
</head>
<body>

</body>
</html>